#!/usr/bin/python
#!-*- coding:utf-8 -*-
# Copyright 2011 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from wsgiref import simple_server
import optparse
import StringIO
import sys
import urllib

import pfif

SERIALIZER = pfif.PFIF_VERSIONS['1.2']


def Serialize(people):
  xml_file = StringIO.StringIO()
  SERIALIZER.write_file(xml_file, people, lambda p: p['notes'])
  xml = xml_file.getvalue()
  return xml


def ParseQuery(query_string):
  parameters = {}
  for parameter in query_string.split('&'):
    if parameter.find('=') >= 0:
      (key, value) = parameter.split('=', 2)
      parameters[key] = value
  return parameters


def MatchQuery(first, last, query):
  query = query.decode('utf-8')
  return (first == query or
          last == query or
          first + last == query or
          first + u' ' + last == query)

class MockPfServer:
  def __init__(self, port):
    self.port = port

  def SetPeopleData(self, people):
    self.people = people

  def run(self):
    self.server = simple_server.make_server('', self.port, self.Dispatch)
    print 'Running mock pfserver, port=%d' % self.port
    sys.stdout.flush()
    self.server.serve_forever()

  def shutdown(self):
    self.server.shutdown()

  def Dispatch(self, environ, start_response):
    path = environ['PATH_INFO']
    method = environ['REQUEST_METHOD']
    query = environ['QUERY_STRING']
    parameters = ParseQuery(query)

    if path == '/api/search':
      if method.upper() == 'GET':
        people = self.SearchPeople(urllib.unquote_plus(parameters['q']))

        xml = Serialize(people)
        print xml

        start_response('200 OK', [('Content-type', 'text/xhtml+xml')])
        return xml
    elif path == '/api/read':
      if method.upper() == 'GET':
        person_id = parameters['id']
        print person_id
        person = self.GetPerson(person_id)

        xml = Serialize([person])
        print xml

        start_response('200 OK', [('Content-type', 'text/xhtml+xml')])

        return xml

    start_response('404 Not Found', [('Content-type', 'text/plain')])
    return '404'

  def SearchPeople(self, query):
    return [person for person in self.people
            if MatchQuery(person['first_name'], person['last_name'], query)]

  def GetPerson(self, id):
    people = [person for person in self.people
              if person['person_record_id'] == id]
    if len(people) == 0:
      return False
    elif len(people) == 1:
      return people[0]
    else:
      raise 'Illegal data: person id duplicated (id=' + id + ')'


if __name__ == '__main__':
  parser = optparse.OptionParser()
  parser.add_option('-p', '--port', type='int', default=8081,
                    help='appserver port number (default: 8081)')
  options, args = parser.parse_args()

  server = MockPfServer(options.port)

  SamplePeople = [
      {'person_record_id': '12345',
       'author_name': u'投稿太郎',
       'last_name': u'山田',
       'first_name': u'花子',
       'entry_date': '2011-03-14T14:41:39Z',
       'notes': [
           {'note_record_id': '98765',
            'person_record_id': '12345',
            'author_name': 'author_name',
            'entry_date': '2011-03-14T14:41:39Z',
            'found': 'true',
            'text': u'坊主が屏風に上手に坊主の絵を書いた',
            },
           ]},
      {'person_record_id': '11111',
       'author_name': u'投稿太郎',
       'last_name': u'山田',
       'first_name': u'たろー',
       'entry_date': '2011-03-14T14:41:39Z',
       'notes': [
           {'note_record_id': '98765',
            'person_record_id': '11111',
            'author_name': 'author_name',
            'entry_date': '2011-03-14T14:41:39Z',
            'found': 'true',
            'text': u'一発貫太くん',
            },
           ]},
      ]
  server.SetPeopleData(SamplePeople)

  server.run()
